import json
import logging

import notifications.models
from django.test import TestCase
from rest_framework.test import APIClient, force_authenticate, APIRequestFactory
from rest_framework import status
from users.models import UserInfo
from notice.views import *
from notifications.models import Notification

log = logging


# Create your tests here.
class UnitNoticeTest(TestCase):
    def setUp(self):
        log.info("enter setUp")
        self.factory = APIRequestFactory()
        post_man = UserInfo.objects.create_user(
            username='test_post_man',
            is_staff=True
        )
        receive_man = UserInfo.objects.create_user(
            username='test_get_man',
        )
        notice1 = Notification.objects.create(
            recipient_id=receive_man.id,
            unread=True,
            actor=post_man,
            verb="test1",
            description='test1',
            level='info',
            public=False,
            deleted=False,
            emailed=False
        )
        notice2 = Notification.objects.create(
            recipient_id=receive_man.id,
            unread=True,
            actor=post_man,
            verb="test2",
            description='test2',
            level='info',
            public=False,
            deleted=False,
            emailed=False
        )

    def test_unread_notifications_list(self):
        log.info("start: test_unread_notifications_list")
        factory = self.factory
        view = UnreadNotificationsList.as_view({'get': 'list'})
        request = factory.get(path='/notice/unread/')
        force_authenticate(request, UserInfo.objects.get(id=2))
        response = view(request)
        response.render()
        result = json.loads(response.content)
        self.assertEqual(2, len(result))
        self.assertEqual(2, result[0]['id'])
        self.assertEqual(1, result[1]['id'])

    def test_mark_all_as_read(self):
        log.info("start: test_unread_notifications_list")
        factory = self.factory
        request = factory.get(path='/notice/mark-all-as-read/')
        view = MarkAllAsRead.as_view()
        force_authenticate(request, UserInfo.objects.get(id=2))
        response = view(request)
        response.render()
        self.assertEqual(b'', response.content)
        request = factory.get(path='/notice/unread_count/')
        force_authenticate(request, UserInfo.objects.get(id=2))
        view = UnreadNotificationCount.as_view()
        response = view(request)
        response.render()
        self.assertEqual(0, json.loads(response.content)['unread_count'])

    def test_mark_as_read(self):
        log.info("start: test_mark_as_read")
        factory = self.factory
        request = factory.get(path='/notice/mark-as-read/2/')
        view = MarkAsRead.as_view()
        force_authenticate(request, UserInfo.objects.get(id=2))
        response = view(request, notification_id=2)
        response.render()
        self.assertEqual(b'', response.content)
        request = factory.get(path='/notice/unread_count/')
        force_authenticate(request, UserInfo.objects.get(id=2))
        view = UnreadNotificationCount.as_view()
        response = view(request)
        response.render()
        self.assertEqual(1, json.loads(response.content)['unread_count'])

    def test_mark_as_unread(self):
        log.info("start: test_mark_as_unread")
        factory = self.factory
        request = factory.get(path='/notice/mark-as-read/2/')
        view = MarkAsRead.as_view()
        force_authenticate(request, UserInfo.objects.get(id=2))
        response = view(request, notification_id=2)
        response.render()
        self.assertEqual(b'', response.content)
        request = factory.get(path='/notice/mark-as-unread/')
        force_authenticate(request, UserInfo.objects.get(id=2))
        view = MarkAsUnread.as_view()
        response = view(request, notification_id=2)
        response.render()
        self.assertEqual(b'', response.content)
        request = factory.get(path='/notice/unread_count/')
        force_authenticate(request, UserInfo.objects.get(id=2))
        view = UnreadNotificationCount.as_view()
        response = view(request)
        response.render()
        self.assertEqual(2, json.loads(response.content)['unread_count'])

    def test_notice_delete(self):
        log.info("start: test_notice_delete")
        factory = self.factory
        request = factory.delete(path='/notice/delete/2/')
        force_authenticate(request, UserInfo.objects.get(id=2))
        view = NoticeDelete.as_view()
        response = view(request, notification_id=2)
        response.render()
        self.assertEqual(b'', response.content)
        self.assertEqual(status.HTTP_200_OK, response.status_code)
        request = factory.get(path='/notice/unread_count/')
        force_authenticate(request, UserInfo.objects.get(id=2))
        view = UnreadNotificationCount.as_view()
        response = view(request)
        response.render()
        self.assertEqual(1, json.loads(response.content)['unread_count'])

    def test_add_notification(self):
        log.info("start: test_add_notification")
        factory = self.factory
        data = {
            'recipient': {
                'id': 1
            },
            'actor': {
                'id': 1
            },
            'verb': 'todo',
            'level': 'warning',
            'description': 'test',
            'unread': True,
            'public': False,
            'deleted': False,
            'emailed': False
        }
        request = factory.post(path="/notice/add/", data=data, format='json')
        force_authenticate(request, UserInfo.objects.get(id=1))
        view = AddNotification.as_view()
        response = view(request)
        response.render()
        self.assertEqual(3, json.loads(response.content)['id'])

    def test_all_notification(self):
        log.info("start: test_add_notification")
        factory = self.factory
        request = factory.get('/notice/all/')
        force_authenticate(request, UserInfo.objects.get(id=2))
        view = AllNotification.as_view({'get': 'list'})
        response = view(request)
        response.render()
        self.assertEqual(2, len(json.loads(response.content)))

    def test_unread_notification_count(self):
        log.info("start: test_unread_notification_count")
        factory = self.factory
        view = UnreadNotificationCount.as_view()
        request = factory.get('/notice/unread_count/')
        force_authenticate(request, UserInfo.objects.get(id=2))
        response = view(request)
        response.render()
        self.assertEqual(2, json.loads(response.content)['unread_count'])

    def test_all_notification_count(self):
        log.info("start: test_all_notification_count")
        factory = self.factory
        view = AllNotification.as_view({'get': 'list'})
        request = factory.get('/notice/all/')
        force_authenticate(request, UserInfo.objects.get(id=2))
        response = view(request)
        response.render()
        self.assertEqual(2, len(json.loads(response.content)))

    def test_notification_for_all(self):
        log.info("start: test_notification_for_all")
        factory = self.factory
        data = {
            'actor': {
                'id': 1
            },
            'verb': 'todo',
            'level': 'warning',
            'description': 'test',
            'unread': True,
            'public': False,
            'deleted': False,
            'emailed': False
        }
        view = NotificationForAllViewSet.as_view()
        request = factory.post('/notice/create_to_all/', data, format='json')
        force_authenticate(request, UserInfo.objects.get(id=1))
        response = view(request)
        response.render()
        self.assertEqual(200, response.status_code)
        force_authenticate(request, UserInfo.objects.get(id=2))
        response = view(request)
        response.render()
        self.assertEqual(403, response.status_code)